package top.goldenyear.porpoise.system.setting.service;

import cn.hutool.v7.core.text.StrUtil;
import com.easy.query.api.proxy.client.EasyEntityQuery;
import com.easy.query.solon.annotation.Db;
import java.util.List;
import lombok.extern.slf4j.Slf4j;
import org.noear.solon.annotation.Component;
import org.noear.solon.annotation.Inject;
import top.goldenyear.porpoise.common.core.exception.ErrorCode;
import top.goldenyear.porpoise.common.core.exception.ServiceException;
import top.goldenyear.porpoise.framework.web.core.annotation.Deform;
import top.goldenyear.porpoise.framework.web.core.model.PageResult;
import top.goldenyear.porpoise.framework.web.core.model.query.QPage;
import top.goldenyear.porpoise.framework.web.core.service.BaseService;
import top.goldenyear.porpoise.system.setting.dto.DictSearchReq;
import top.goldenyear.porpoise.system.setting.model.Dict;
import top.goldenyear.porpoise.system.setting.model.DictItem;
import top.goldenyear.porpoise.system.setting.model.proxy.DictProxy;

/**
 * 字典表 Service 服务层
 *
 * @author airhead
 * @since 2024-10-15
 */
@Component
@Slf4j
public class DictService extends BaseService<Dict, DictProxy> {
  @Db private EasyEntityQuery easyEntityQuery;
  @Inject private DictItemService dictItemService;

  public DictService() {
    super(Dict.class, DictProxy.class);
  }

  public Boolean createDict(Dict dict) {
    Boolean exists = exists("code", dict.getCode(), "id", null);
    if (exists) {
      throw new ServiceException(
          ErrorCode.builder().msg(String.format("字典编码已存在, %s", dict.getCode())).build());
    }

    return save(dict);
  }

  public Boolean updateDict(Dict dict) {
    Dict dbDict = getById(dict.getId());
    if (dbDict == null) {
      throw new ServiceException(
          ErrorCode.builder().msg(String.format("字典不存在, %d", dict.getId())).build());
    }

    boolean changeCode = !dbDict.getCode().equals(dict.getCode());
    if (changeCode) {
      Boolean exists = exists("code", dict.getCode(), "id", dict.getId());
      if (exists) {
        throw new ServiceException(
            ErrorCode.builder().msg(String.format("字典编码已存在, %s", dict.getCode())).build());
      }
    }

    boolean update = updateById(dict);
    if (update && changeCode) {
      // 如果编码不能为空
      if (StrUtil.isNotBlank(dbDict.getCode())) {
        DictItem query = new DictItem();
        query.setDictCode(dbDict.getCode());
        List<DictItem> configList = dictItemService.list(query);
        for (DictItem dictItem : configList) {
          dictItem.setDictCode(dict.getCode());
        }

        dictItemService.batchUpdate(configList);
      }
    }

    Boolean exists = exists("code", dict.getCode(), "id", dict.getId());
    if (exists) {
      throw new ServiceException(
          ErrorCode.builder().msg(String.format("字典编码已存在, %s", dict.getCode())).build());
    }

    return updateById(dict);
  }

  public Dict getDict(Integer id) {
    return getById(id);
  }

  public Boolean deleteDict(Integer id) {
    if (getById(id) == null) {
      throw new ServiceException(ErrorCode.builder().msg("字典不存在").build());
    }

    Dict dict = getById(id);
    if (dict == null) {
      throw new ServiceException(ErrorCode.builder().msg("字典不存在").build());
    }

    DictItem query = new DictItem();
    query.setDictCode(dict.getCode());
    long count = dictItemService.count(query);
    if (count > 0) {
      throw new ServiceException(ErrorCode.builder().msg("字典下已存在字典项，请先删除字典项").build());
    }

    return deleteById(id);
  }

  public Boolean batchDelDict(List<Integer> ids) {
    for (Integer id : ids) {
      if (getById(id) == null) {
        throw new ServiceException(ErrorCode.builder().msg("字典不存在").build());
      }
    }

    return deleteByIds(ids);
  }

  public List<Dict> listDict(Dict dict) {
    return list(dict);
  }

  @Deform(keep = {"code", "name"})
  public List<Dict> simpleListDict(Dict dict) {
    return list(dict);
  }

  public PageResult<Dict> paginateDict(QPage qPage, DictSearchReq searchReq) {
    return paginate(
        qPage,
        dictProxy -> {
          dictProxy.status().eq(searchReq.getStatus());
          dictProxy.or(
              () -> {
                dictProxy.name().like(searchReq.getKeyword());
                dictProxy.code().like(searchReq.getKeyword());
              });
        });
  }

  @Override
  protected EasyEntityQuery easyEntityQuery() {
    return easyEntityQuery;
  }
}
